Skip to main content

第 8 章:引入機密資料 Secrets

什麼是 Secret

Secrets 是 Kubernetes 提供開發者一種存放敏感資訊的方式。

Kubernetes 本身也使用相同的機制存放 access token,限制 API 的存取權限,確保不會有外部服務隨意操作 Kubernetes API

三種方式來引用 Secret

  • 將 Secrets 當成 環境變數(environment variables) 使用
  • 將 Secrets File 掛載在 Pod 某個檔案路徑底下使用
  • 將這些 sensitive data 統一存放在某一個 Docker Image 中,並將這個 Image 存放在私有的 Image Registry 中,透過 image pull 下載到 Kubernetes Cluster 中,讓其他 Pods 存取

使用 Secret 的用途

  • 儲存機密資料為物件
  • 預先儲存資料為之後用
  • 密碼 (passwords)、API tokens、密鑰(Key)和憑證(Certification)

Secrets 屬性

  • 透過 base64 編碼
  • 可設定加密
  • 儲存在 ETCD
  • 透過 Namespace 切分使用權
  • 如果相關 Secret 無法被調用,則 Pod 無法啟動

建立 Secrets

  • 單純透過 kubectl 建立 Secrets
kubectl create secret generic mysql-secret \
--from-literal=MYSQL_ROOT_PASSWORD=root \
--from-literal=MYSQL_USER=demo \
--from-literal=MYSQL_PASSWORD=demo
kubectl get secrets
NAME TYPE DATA AGE
mysql-secret Opaque 3 16s
  • 透過文件與 kubectl 建立 Secrets
echo -n "root" > ./username.txt
echo -n "rootpass" > ./password.txt
kubectl create secret generic account-secret \
--from-file=./username.txt \
--from-file=./password.txt
  • 透過 YAML file

secret 的值需要經過 base64 編碼

encode

echo root | base64
cm9vdAo=
echo demo | base64
ZGVtbwo=

decode

echo ZGVtbw== | base64 --decode
demo
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque
data:
MYSQL_PASSWORD: ZGVtbw==
MYSQL_ROOT_PASSWORD: cm9vdA==
MYSQL_USER: ZGVtbw==

透過 kuectl create 創建一個新物件,

kubectl create -f my-secret.yaml
secret/mysql-secret created
  • 透過 config file
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
stringData:
config.yaml: |
MYSQL_ROOT_PASSWORD: root
MYSQL_PASSWORD: demo
MYSQL_USER: demo

在 Pods 中使用 Secret

  • 將 Secrets 當成環境變數 (environment variables) 使用
mysql.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: MYSQL_ROOT_PASSWORD
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: mysql-secret
key: MYSQL_USER
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: MYSQL_PASSWORD

或是使用以下方法

mysqlenvFrom.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
envFrom:
- secretRef:
name: mysql-secret

若是該 Secret 物件是從 --from-file 創建,那麼檔案名稱當成 key ,檔案內容當成 value

使用 kubectl create 創建 my-pod ,指令如下

kubectl apply -f mysql.yaml
pod/mysql created
kubectl exec -it mysql -- /bin/bash
bash-4.4# echo $MYSQL_USER
demo
  • 將 Secrets File 掛載在 Pod 某個檔案路徑底下使用
my-pod-with-mounting-secret.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod-with-mounting-secret
labels:
app: webserver
spec:
containers:
- name: demo-pod
image: zxcvbnius/docker-demo
ports:
- containerPort: 3000
volumeMounts:
- name: secret-volume
mountPath: /etc/creds
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: mysql-secret

使用 kubectl create 指令創建一個新的 Pod 物件,

kubectl create -f ./my-pod-with-mounting-secret.yaml
pod "my-pod-with-mounting-secret" create
kubectl exec -it my-pod-with-mounting-secret -- /bin/bash
ls /etc/creds
MYSQL_PASSWORD MYSQL_ROOT_PASSWORD MYSQL_USER
echo $(cat /etc/creds/MYSQL_PASSWORD)
demo